<template>
    <el-dialog v-model="data.open" :title="data.title" width="50%" draggable align-center>
        <el-form :model="formData" label-width="120px" :inline="true" :rules="rules" ref="form">
            <el-row>
                <el-col :span="12">
                    <el-form-item label="菜单名称" prop="name">
                        <el-input class="el-form-width-all" v-model="formData.name" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="上级菜单">
                        <el-tree-select class="el-form-width-all" v-model="formData.parentId" :data="menuListData"
                            :render-after-expand="false" check-strictly clearable />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="12">
                    <el-form-item label="路径">
                        <el-input class="el-form-width-all" v-model="formData.path" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="图标">
                        <el-input class="el-form-width-all" v-model="formData.icon" clearable />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-form-item label="是否启用">
                    <el-switch class="el-form-width-all" v-model="formData.visible" />
                </el-form-item>
            </el-row>
            <el-row>
                <el-form-item label="关联角色" prop="relationRoles">
                    <el-checkbox-group v-model="formData.relationRoles">
                        <el-checkbox v-for="item in roleData" :label="item.name" name="relationRoles" />
                    </el-checkbox-group>
                </el-form-item>
            </el-row>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button type="primary" @click="confirm(form)">确定</el-button>
                <el-button @click="cancel">取消</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script setup lang = "ts">
import { menuItemList } from '@/api/portal'
import type { MenuType } from '@/assets/js/portal/MenuType'
import type { HttpResponse } from '@/assets/js/utils/entity/HttpResponse'
import { ElMessage, getPositionDataWithUnit, type FormInstance, type FormRules } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
import { getRoleOne, saveMenu } from '@/api/settings/menuManagement'
import type { SysMenu } from '@/assets/js/vo/settings/menuManagement/VMenuManagement'
import { roleList } from '@/api/settings/roleManagement'
import type { TableSelectOne } from '@/assets/js/utils/entity/TableCardType'

const props = defineProps<{
    data: TableSelectOne
}>()

let formData = reactive<SysMenu>({
    name: null,
    parentId: null,
    visible: true,
    relationRoles: []
})

type role = {
    id: string,
    name: string,
    code: string,
    status: boolean
}

const roleMap = new Map<string, string>()
const roleMap2 = new Map<string, string>()
const roleData = reactive<role[]>([])

onMounted(() => {
    getRoleList()
    getData()
})

const getRoleList = async () => {
    const res = await roleList() as unknown as HttpResponse<role[]>
    if (res.ok) {
        res.data!.forEach((item: role) => {
            roleData.push(item)
            roleMap.set(item.name, item.id)
            roleMap2.set(item.id, item.name)
        })
    }
}

const getData = async () => {
    if (props.data.id !== null) {
        const res = await getRoleOne(props.data.id as string) as unknown as HttpResponse<SysMenu>
        if (res.ok) {
            const data = res.data as SysMenu
            formData.id = data.id
            formData.icon = data.icon
            formData.name = data.name
            formData.parentId = data.parentId
            formData.path = data.path
            formData.visible = data.visible
            formData.relationRoles!.splice(0)
            data.relationRoles?.forEach(roleStr => {
                formData.relationRoles?.push(roleMap2.get(roleStr) as string)
            })
        }
    }
}

const form = ref<FormInstance>()
const rules = reactive<FormRules>({
    name: [
        { required: true, message: '菜单名称为必填', trigger: 'blur' }
    ],
    relationRoles: [
        { required: true, message: '请选择关联角色', trigger: 'blur' }
    ]
})

let menuListData = reactive<Array<MenuType>>([])

const getMenuList = async () => {
    const res = await menuItemList() as unknown as HttpResponse<Array<MenuType>>
    if (res.ok) {
        res.data?.forEach(item => {
            menuListData.push(item)
        })
    }
}
getMenuList()

const confirm = (form: FormInstance | undefined) => {
    if (!form) return
    form.validate(async (valid, fields) => {
        if (valid) {
            // 存储
            const params = {
                entity: {
                    id: formData.id,
                    name: formData.name,
                    parentId: formData.parentId,
                    path: formData.path,
                    icon: formData.icon,
                    visible: formData.visible
                },
                relationRoles: (() => {
                    const arr: string[] = []
                    if (formData.relationRoles && formData.relationRoles.length) {
                        formData.relationRoles.forEach(r => {
                            arr.push(roleMap.get(r) as string)
                        })
                    }
                    return arr
                })()
            }
            const res = await saveMenu(params) as unknown as HttpResponse
            if (res.ok) {
                props.data.open = false
                ElMessage.success({
                    message: '保存成功',
                    type: 'success'
                })
            }
        } else {
            console.log('error submit!', fields)
        }
    })
}
const cancel = () => {
    props.data.open = false
}
</script>

<style lang = "less" scoped></style>